// *** LICENSE HEADER ***
// Filename: ./camera.cpp
// This file is part of Nodewarz 0.1
// Nodewarz is a 3d OpenGL strategy game
// Copyright (C) 2007 CZestmyr
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
// *** END LICENSE HEADER ***
#include "camera.h"

camera::camera() {
    Reset();
}

void camera::Reset() {
    zoomSpeed = 0.0f;
    //Rotation of the WORLD
    horAngle = 0.0f;
    vertAngle = -40.0f;
    //Position of the CAMERA
    position[0] = 0.0f;
    position[1] = 0.0f;
    zoom = 50.0f;
    leftRot = rightRot = upRot = downRot = false;
}

void camera::Update(Uint32 dt) {
    //Move the camera, if it is moving and constraint its position
    if (zoomAccel != 0.0f) {
        zoomSpeed += dt * zoomAccel;
        Constraintf(zoomSpeed, -_CAMERA_MAX_ZOOM_SPEED, _CAMERA_MAX_ZOOM_SPEED);
    } else if (zoomSpeed > 0.0f) {
        zoomSpeed -= dt * _CAMERA_FRICTION;
        Constraintf(zoomSpeed, 0.0f, _CAMERA_MAX_ZOOM_SPEED);
    } else {
        zoomSpeed += dt * _CAMERA_FRICTION;
        Constraintf(zoomSpeed, -_CAMERA_MAX_ZOOM_SPEED, 0.0f);
    }

    if ((zoomSpeed > 0.0f && zoom <= _CAMERA_MAX_Z) ||
            (zoomSpeed < 0.0f && zoom >= _CAMERA_MIN_Z)) {
        zoom += zoomSpeed * dt;
        if (Constraintf(zoom, _CAMERA_MIN_Z, _CAMERA_MAX_Z))
            zoomSpeed = 0.0f;
    }
    float dHorAngle, dVerAngle;
    if (leftRot && !rightRot)
        dHorAngle = dt * + _CAMERA_ROT_SPEED;
    else if (rightRot && !leftRot)
        dHorAngle = dt * -_CAMERA_ROT_SPEED;
    else
        dHorAngle = 0.0f;
    horAngle += dHorAngle;
    if (upRot && !downRot)
        dVerAngle = dt * -_CAMERA_VERT_ROT_SPEED;
    else if (downRot && !upRot)
        dVerAngle = dt * _CAMERA_VERT_ROT_SPEED;
    else
        dVerAngle = 0.0f;
    vertAngle += dVerAngle;
    Constraintf(vertAngle, -_CAMERA_MAX_VERT, -_CAMERA_MIN_VERT);
}

void camera::Draw() {
    //This doesn't draw anything but it sets the transformation matrices for other things that should be drawn
    glLoadIdentity();

    glTranslatef(0.0f, 0.0f, -zoom);
    glRotatef(vertAngle, 1.0f, 0.0f, 0.0f);
    glRotatef(horAngle, 0.0f, 0.0f, 1.0f);
    glTranslatef(-position[0], -position[1], 0.0f);
}

void camera::Move(float dx, float dy) {
    //Shift the camera on the game board (with mouse)
    dx *= zoom / 250.0f;
    dy *= zoom / 250.0f;
    float s = sin(horAngle * _DEG2RAD);
    float c = cos(horAngle * _DEG2RAD);
    position[0] = position[0] - c * dx + s * dy;
    position[1] = position[1] + s * dx + c * dy;
}

void camera::RotateLeft() {
    leftRot = true;
}
void camera::RotateRight() {
    rightRot = true;
}
void camera::RotateUp() {
    upRot = true;
}
void camera::RotateDown() {
    downRot = true;
}
void camera::EndRotateLeft() {
    leftRot = false;
}
void camera::EndRotateRight() {
    rightRot = false;
}
void camera::EndRotateUp() {
    upRot = false;
}
void camera::EndRotateDown() {
    downRot = false;
}

void camera::ZoomOut() {
    zoomAccel = _CAMERA_ZOOM_ACCEL;
}

void camera::ZoomIn() {
    zoomAccel = -_CAMERA_ZOOM_ACCEL;
}

void camera::ZoomStop() {
    zoomAccel = 0.0f;
}
